package dper.study.codes.elasticsearch.utils;

import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.suggest.SuggestResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.suggest.SuggestBuilder;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.List;

/**
 * Created by leichen on 2017/3/13.
 */
@Component("elasticsearchUtil")
public class ElasticsearchUtil {

    private Client client = null;
    private static final int PORT = 9300;


    public ElasticsearchUtil(String clusterName, String ipAddress) {
        Settings settings = Settings
                .settingsBuilder()
                .put("cluster.name",clusterName)
                .put("client.transport.sniff", true)
                .build();
        try {
            client = TransportClient.builder().settings(settings).build()
                    .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(ipAddress), PORT));
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建索引
     * @param indexName 索引名称，相当于数据库名称
     * @param typeName 索引类型，相当于数据库中的表名
     * @param id id名称，相当于每个表中某一行记录的标识
     * @param jsonData json数据
     */
    public IndexResponse createIndex(String indexName, String typeName, String id,
                                     String jsonData) {
        IndexRequestBuilder requestBuilder = client.prepareIndex(indexName,
                typeName,id).setRefresh(true);//设置索引名称，索引类型
        IndexResponse indexResponse = requestBuilder.setSource(jsonData).execute().actionGet();//创建索引
        return indexResponse ;
    }

    /**
     * 批量创建索引
     * @param indexName 索引名称，相当于数据库名称
     * @param typeName 索引类型，相当于数据库中的表名
     * @param jsonDataList json list数据
     */
    public BulkResponse createBulkIndex(String indexName, String typeName,
                                        List<String> jsonDataList) {
        BulkRequestBuilder bulkRequestBuilder = client.prepareBulk() ;
        for(String jsonData:jsonDataList){
            bulkRequestBuilder.add(client.prepareIndex(indexName,typeName).setSource(jsonData).setRefresh(true)) ;
        }
        BulkResponse bulkResponse = bulkRequestBuilder.execute().actionGet();
        return bulkResponse ;
    }




    /**
     * 执行搜索
     * @param indexName 索引名称
     * @param typeName 索引类型
     * @param queryBuilder 查询条件
     * @return
     */
    public SearchResponse searcher(String indexName, String typeName,
                                   QueryBuilder queryBuilder) {
        SearchResponse searchResponse = client.prepareSearch(indexName)
                .setTypes(typeName).setQuery(queryBuilder).execute()
                .actionGet();//执行查询
        return searchResponse;
    }

    /**
     * 单独执行suggest搜索
     * @param indexName 索引名称
     * @param suggestionBuilder 查询条件
     * @return
     */
    public SuggestResponse suggestSearcher(String indexName,
                                           SuggestBuilder.SuggestionBuilder suggestionBuilder) {
        SuggestResponse searchResponse = client.prepareSuggest(indexName).addSuggestion(suggestionBuilder).execute()
                .actionGet();//执行查询
        return searchResponse;
    }



    /**
     * 更新索引
     * @param indexName 索引名称
     * @param typeName 索引类型
     * @param id id名称
     * @param jsonData json数据
     */
    public UpdateResponse updateIndex(String indexName, String typeName, String id,
                                      String jsonData) {
        UpdateRequest updateRequest = new UpdateRequest();
        updateRequest.index(indexName);//设置索引名称
        updateRequest.id(id);//设置id
        updateRequest.type(typeName);//设置索引类型
        updateRequest.doc(jsonData);//更新数据
        UpdateResponse updateResponse =  client.update(updateRequest).actionGet();//执行更新
        return updateResponse ;
    }


    /**
     * 删除索引
     * @param indexName
     * @param typeName
     * @param id
     */
    public void deleteIndex(String indexName, String typeName, String id) {
        client.prepareDelete(indexName, typeName, id).get();
    }

    public  static void main(String[] argv){
        ElasticsearchUtil elasticsearchUtil = new ElasticsearchUtil("cl-es-cluster","localhost") ;
        SearchResponse searchResponse = elasticsearchUtil.searcher("first_index", "first_type", QueryBuilders.matchAllQuery()) ;
        System.out.println(searchResponse.toString());
    }

}
